#include "platform.h"


GPIOI2C_BusStateDef GPIOI2C_Bus_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_AHBPeriphClockCmd(I2C1_SCL_BUSCLK, ENABLE);
	RCC_AHBPeriphClockCmd(I2C1_SDA_BUSCLK, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIOI2C_SCL_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_High;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

	GPIO_Init(GPIOI2C_SCL_GPIO_PORT, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIOI2C_SDA_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_High;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_Init(GPIOI2C_SCL_GPIO_PORT, &GPIO_InitStructure);
  
	SDA_H;
	SCL_H;
	return GPIOI2C_BUS_IDLE;
}

void GPIOI2C_Bus_DeInit(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_AHBPeriphClockCmd(I2C1_SCL_BUSCLK, ENABLE);
	RCC_AHBPeriphClockCmd(I2C1_SDA_BUSCLK, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIOI2C_SCL_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_High;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

	GPIO_Init(GPIOI2C_SCL_GPIO_PORT, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIOI2C_SDA_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_High;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_Init(GPIOI2C_SCL_GPIO_PORT, &GPIO_InitStructure);
}

///***********************************************************************************************************************
//  * @brief  Collect temperature information
//  * @note   none
//  * @param  Cap_Structure:CAP AFE information
//  * @param  times:Average times
//  * @retval none
//  *********************************************************************************************************************/
//void GetVT(CAP_AFE* Cap_Structure, u16 times)
//{
//	uint16_t adc_err=0;
//    u32 adc_count=0,val1=0,val=0;
//	u8 cfg;
//	float Vref=0,Vin=0;
//	
//	uint16_t CalibrationData = *(uint16_t *)(0x1FFFF7E0);	//Get ADC calibration coefficients
//	float  VrefCalculation = (float)CalibrationData * (float)3.3 / (float)4095.0;	
//	
//  CAP_AFE_Transmit(I2C_ADDR,RCNT_MSB,0xff);	
//	CAP_AFE_Transmit(I2C_ADDR,RCNT_LSB,0xff);//Extend measurement time
//	
//	USART_Cmd(USART1, 0);
//	GPIOA->AFRL |=0xf<<28;	
//	MCO_PIN_OUT(0);	//Turn off external clock
//	
//	GPIOA->AFRL &=~(0xf<<12);
//	GPIOA->CRL &=~(0xf<<12);  
//	GPIOA->CRL |=0x03<<12; 		
//	GPIOA->BRR |= GPIO_Pin_3;	// Pull down the Rx pin to prevent overcurrent
//	
//	CAP_AFE_Receive(I2C_ADDR,CFG,&cfg);	
//	cfg &=~(0x03) ;
//	cfg |=OS_SD_Single_Trans;	
//	CAP_AFE_Transmit(I2C_ADDR,CFG,cfg);//Enable CAP AFE measurement
//	ADC_Cmd(ADC1, ENABLE);	//Enable ADC measurement
//	for(adc_count=0;adc_count<times;adc_count++)	
//	{
//		ADC1->CHANY0 &= ~(0XF<<0);	
//		ADC1->CHANY0 |= 8<<0;
//		ADC1->ADCR |= ADC_ADCR_ADST;
//		while (RESET == ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
//		ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
//		val1 = ADC1 ->ADDR8&0xfff;	//Get external reference voltage
//		Vref+=(float)4095.0 * (float)VrefCalculation / (float)val1;
//		
//		ADC1->CHANY0 &= ~(0XF<<0);
//		ADC1->CHANY0 |= 1<<0;
//		ADC1->ADCR |= ADC_ADCR_ADST;
//		while (RESET == ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
//		ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
//		val += ADC1 ->ADDR1&0xfff;	//Get VT voltage
//	}
//	Vin =val/4095.0*Vref/adc_count; 
//	Cap_Structure->VDD = Vref/adc_count;
//	ADC_Cmd(ADC1, DISABLE); 
//	cfg &=~(0x03) ;
//	cfg |=OS_SD_Stop_Trans;
//	CAP_AFE_Transmit(I2C_ADDR,CFG,cfg);	
//	Delay_ms(20);
//	CAP_AFE_Transmit(I2C_ADDR,RCNT_MSB,0x5c);
//	CAP_AFE_Transmit(I2C_ADDR,RCNT_LSB,0xd0);	//Restore measurement time
//	
//	GPIOA->AFRL &=~(0xf<<28|0xf<<12);	
//	GPIOA->AFRL |=0x3<<28;	//af3
//	GPIOA->CRL &=~(0xf<<28|0x08<<12);  
//	GPIOA->CRL |=0x09<<28|0x08<<12; 	
//	GPIOA->AFRL &=~(0xf<<12);
//	GPIOA->AFRL |=0x1<<12;	//af1	
//	GPIOA->BSRR |= GPIO_Pin_3;	//Configure Rx pins
//	
//	USART_Cmd(USART1, ENABLE);
//	
//	
//	if(Cap_Structure->VT==0)Cap_Structure->VT=Vin/(times-adc_err);
//	else Cap_Structure->VT=Cap_Structure->VT*0.4+Vin/(times-adc_err)*0.6;	//VT filter
//		
//}


/***********************************************************************************************************************
  * @brief  Measure VT initialization
  * @note   none
  * @param  none
  * @retval none
  *********************************************************************************************************************/
void VT_Init(CAP_AFE* Cap_Structure)
{
	ADC_InitTypeDef  ADC_InitStruct;
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_StructInit(&GPIO_InitStruct);
	ADC_StructInit(&ADC_InitStruct);
	
	RCC_APB1PeriphClockCmd(RCC_APB1ENR_ADC1, ENABLE); //Enable ADC clock
	RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB|RCC_AHBENR_GPIOA, ENABLE);
	
	GPIO_InitStruct.GPIO_Pin  =  Cap_Structure->VT_CH.vt_gpio;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; //GPIO mode
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	                                          
	
	ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
	ADC_InitStruct.ADC_Prescaler = ADC_Prescaler_17;   //48M/17
	ADC_InitStruct.ADC_Mode = ADC_Mode_Scan;   //Set ADC mode
	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;   //AD data right-justified
	ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExtTrig_T1_CC1;

	ADC_Init(ADC1, &ADC_InitStruct);
	   
	ADC1->ADCFG |= ADC_SampleTime_2_5|ADC_ADCFG_VSEN;
	ADC1->ANY_CR |=ADC_ANY_CR_CHANY_MDEN;

	ADC_Cmd(ADC1, DISABLE); 
}

/***********************************************************************************************************************
  * @brief  CAP AFE External clock initialization
  * @note   none
  * @param  none
  * @retval none
  *********************************************************************************************************************/
void CLKIN_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_StructInit(&GPIO_InitStruct);

	RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
	
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_3);
	
	GPIO_InitStruct.GPIO_Pin  =  GPIO_Pin_7;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;                           
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;                              
	GPIO_Init(GPIOA, &GPIO_InitStruct);

	RCC_MCOConfig(RCC_MCO_HSI_Div4);//Configure 12M reference clock
}

/***********************************************************************************************************************
  * @brief  CAP AFE hardware reset
  * @note   none
  * @param  none
  * @retval none
  *********************************************************************************************************************/
void CA_HARDWARE_RESET(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Pin  =  SD_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_High;                           
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                              
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	
	GPIO_SetBits(GPIOA,SD_PIN);
	Delay_ms(5);
	GPIO_ResetBits(GPIOA,SD_PIN);
	Delay_ms(5);
}


void Conf_FreDiv(CAP_AFE* Cap_Structure)
{
	if(Cap_Structure->clk == In_CLK)
	{
		switch(Cap_Structure->I_DRIVE)
		{
			case DRIVE_I_3200UA:
				cap_structure.FIN_DIV = FIN_DIV_64;
				break;
			case DRIVE_I_1600UA:
				cap_structure.FIN_DIV = FIN_DIV_32;
				break;
			case DRIVE_I_800UA:
				cap_structure.FIN_DIV = FIN_DIV_16;
				break;
			case DRIVE_I_400UA:
				cap_structure.FIN_DIV = FIN_DIV_8;
				break;
			case DRIVE_I_200UA:
				cap_structure.FIN_DIV = FIN_DIV_4;
				break;
			default:
				cap_structure.FIN_DIV = FIN_DIV_64;
				break;
		}
	}
	else
	{
		switch(Cap_Structure->I_DRIVE)
		{
			case DRIVE_I_3200UA:
				cap_structure.FIN_DIV = FIN_DIV_16;
				break;
			case DRIVE_I_1600UA:
				cap_structure.FIN_DIV = FIN_DIV_8;
				break;
			case DRIVE_I_800UA:
				cap_structure.FIN_DIV = FIN_DIV_2;
				break;
			case DRIVE_I_400UA:
				cap_structure.FIN_DIV = FIN_DIV_2;
				break;
			case DRIVE_I_200UA:
				cap_structure.FIN_DIV = FIN_DIV_0;
				break;
			default:
				cap_structure.FIN_DIV = FIN_DIV_16;
				break;
		}
	}
	cap_structure.FREF_DIV = Fref_NO_DIV;	//Sampling clock without frequency division 0~255
	
	if(cap_structure.clk == In_CLK) cap_structure.clkfre = 1.8/(cap_structure.FREF_DIV+1);	//2.4Mhz sampling frequency
	else if(cap_structure.clk == Ex_CLK) 	cap_structure.clkfre = 12.0/(cap_structure.FREF_DIV+1);	//12Mhz sampling frequency
}


/***********************************************************************************************************************
  * @brief  Initialize CAP AFE
  * @note   none
  * @param  Cap_Structure
  * @retval none
  *********************************************************************************************************************/
void Cap_Afe_Init(CAP_AFE* Cap_Structure)
{
	CA_HARDWARE_RESET();
	
#if defined VT_EN
	VT_Init(Cap_Structure);
#endif
	GPIOI2C_Bus_Init();
	if(Cap_Structure->clk == Ex_CLK)CLKIN_Init();	//CAP AFE External clock initialization
	
	Registers_Init(Cap_Structure);	//CAP_AFE Registers initialization
}


